package com.frostmourne.mxsattributeinventory.listeners;

import com.frostmourne.mxsattributeinventory.MXSAttributeInventory;
import com.frostmourne.mxsattributeinventory.utils.FileUtils;
import com.gitee.mxstars.builder.InventoryBuilder;
import com.gitee.mxstars.builder.ItemBuilder;
import com.gitee.mxstars.mxscript.MXScriptEngine;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class InventoryListener implements Listener {

    @EventHandler
    public void close(InventoryCloseEvent e){
       if (e.getView().getTitle() != null &&
               MXSAttributeInventory.titleMap.containsKey(e.getView().getTitle())
       ){

           String invName = MXSAttributeInventory.titleMap.get(e.getView().getTitle());
           FileUtils.saveDataToFile((Player) e.getPlayer(),invName,e.getInventory());

       }
    }

    @EventHandler
    public void click(InventoryClickEvent e){

        if (e.getView().getTitle() != null &&
                MXSAttributeInventory.titleMap.containsKey(e.getView().getTitle())
        ){
            if (e.getSlot() == 999||e.getSlot() == -999||e.getClickedInventory() == null || e.getClickedInventory() == e.getWhoClicked().getInventory()){
                return;
            }
            Player player = (Player) e.getWhoClicked();

            String invName = MXSAttributeInventory.titleMap.get(e.getView().getTitle());

            InventoryBuilder inventoryBuilder = MXSAttributeInventory.inventoryMap.get(invName);
            Map<String, List<Integer>> slotStrings = inventoryBuilder.getSlotMap();

            Inventory originInv = MXSAttributeInventory.inventoryMap.get(invName).getInv();


            if (e.getCurrentItem().getType().toString().equalsIgnoreCase("AIR")){
                ItemStack barrier = new ItemBuilder("166").getItem();
                ItemStack cursor = e.getCursor();
                e.setCurrentItem(barrier);
                e.setCancelled(true);
                e.setCursor(cursor);
                e.setCurrentItem(null);
                return;
            }

            if (!(originInv.getItem(e.getRawSlot()).isSimilar(e.getCurrentItem()))){
                if (e.getCursor().getType() == Material.AIR){
                    e.setCancelled(true);
                    ItemStack current = e.getCurrentItem().clone();
                    e.setCursor(current);
                    e.setCurrentItem(originInv.getItem(e.getRawSlot()));
                    return;
                }
            }

            if (MXSAttributeInventory.scriptMap.containsKey(invName)){
                String scriptKey = null;
                for (String s : slotStrings.keySet()){
                    if (slotStrings.get(s).contains(e.getRawSlot())){
                        scriptKey = s;
                    }
                }
                if (scriptKey != null) {
                    ConfigurationSection cs = MXSAttributeInventory.scriptMap.get(invName);
                    if (cs.getKeys(false).contains(scriptKey)){
                        ConfigurationSection scriptGroup = cs.getConfigurationSection(scriptKey);
                        if (scriptGroup.getKeys(false).contains("Conditions")){
                            boolean no = false;
                            for (String s : scriptGroup.getStringList("Conditions")) {
                                String type = s;
                                String[] args = s.split(":");
                                if (s.contains(":")) {
                                    type = s.split(":")[0];
                                }
                                switch (type.toUpperCase()) {
                                    case "CURSORLORE":
                                        boolean has = false;
                                        if (e.getCursor() != null && e.getCursor().hasItemMeta() &&
                                        e.getCursor().getItemMeta().hasLore()) {
                                            for (String lore : e.getCursor().getItemMeta().getLore()) {
                                                if (lore.contains(args[1])) {
                                                    has = true;
                                                }
                                            }
                                        }
                                            if (!has) {
                                                no = true;
                                            }
                                            break;
                                    case "HASPERMISSION":
                                                if (!player.hasPermission(args[1])) {
                                                    no = true;
                                                }
                                            break;
                                    default:
                                            break;
                                        }
                                if (no){
                                    e.setCancelled(true);
                                    return;
                                }
                            }

                        }
                        if (scriptGroup.getKeys(false).contains("Scripts")){
                            List<String> scripts = scriptGroup.getStringList("Scripts");
                            Map<String,Object[]> args = new HashMap<>();
                            args.put("CANCEL-EVENT",new Object[]{e});
                            args.put("DEFAULT-CURRENT-TYPE",new Object[]{e});
                            MXScriptEngine.execute(scripts,player,args);
                        }


                    }
                }
            }


        }
    }

    public boolean hasDefaultItem(String invName, ItemStack item){
        InventoryBuilder inventoryBuilder = MXSAttributeInventory.inventoryMap.get(invName);
        return inventoryBuilder.getInv().contains(item);
    }

}
